package com.example.user.util;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Base64;

public class TableFieldEncryptionAndDecryptionHandler implements TypeHandler<String> {

    private static String key = "8dFph568fsDjzzfWQx6/8g==";
    //是否开启加解密操作
    private static Boolean openEncrypt = true;


    public static String loadKey() {
        return key;
    }

    public static boolean loadOpenEncrypt() {
        return openEncrypt;
    }

    /**
     * 入库前加密
     */
    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, String data, JdbcType jdbcType) throws SQLException {
        if (loadOpenEncrypt()) {
            try {
                byte[] keyByte = Base64.getDecoder().decode(loadKey());
                byte[] cipherText = SM4Util.encrypt_ECB_Padding(keyByte, data.getBytes());
                String dataEncrypt = Base64.getEncoder().encodeToString(cipherText);
                System.out.println("1-数据库字段加密-原始值:" + data + ";加密值:" + dataEncrypt);
                preparedStatement.setString(i, dataEncrypt);
            } catch (Exception e) {
                //e.printStackTrace();
                System.out.println("1-数据库字段加密-失败:" + data + "  :  " + e.getMessage());
            }
        } else {
            preparedStatement.setString(i, data);
        }
    }

    /**
     * 出库前解密
     */
    @Override
    public String getResult(ResultSet resultSet, String s) throws SQLException {
        String data = resultSet.getString(s);
        if (loadOpenEncrypt()) {
            if (StringUtils.isNotEmpty(data)) {
                try {
                    byte[] jiemiInput = Base64.getDecoder().decode(data);
                    byte[] keyByte = Base64.getDecoder().decode(loadKey());
                    byte[] decryptedData = SM4Util.decrypt_ECB_Padding(keyByte, jiemiInput);
                    data = new String(decryptedData);
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            }
            System.out.println("1-数据库字段解密-原始值:{" + resultSet.getString(s) + "};解密值:{" + data + "}");
        }
        return data;
    }

    @Override
    public String getResult(ResultSet resultSet, int i) throws SQLException {
        String data = resultSet.getString(i);
        if (loadOpenEncrypt()) {
            String old = new String(data);
            if (StringUtils.isNotEmpty(data)) {
                try {
                    byte[] jiemiInput = Base64.getDecoder().decode(data);
                    byte[] keyByte = Base64.getDecoder().decode(loadKey());
                    byte[] decryptedData = SM4Util.decrypt_ECB_Padding(keyByte, jiemiInput);
                    data = new String(decryptedData);
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            }
            System.out.println("2-数据库字段解密-原始值:{" + old + "};解密值:{" + data + "}");
        }
        return data;
    }

    @Override
    public String getResult(CallableStatement callableStatement, int i) throws SQLException {
        String data = callableStatement.getString(i);
        if (loadOpenEncrypt()) {
            String old = new String(data);
            if (StringUtils.isNotEmpty(data)) {
                try {
                    byte[] jiemiInput = Base64.getDecoder().decode(data);
                    byte[] keyByte = Base64.getDecoder().decode(loadKey());
                    byte[] decryptedData = SM4Util.decrypt_ECB_Padding(keyByte, jiemiInput);
                    data = new String(decryptedData);
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            }
            System.out.println("3-数据库字段解密-原始值:{" + old + "};解密值:{" + data + "}");
        }
        return data;
    }


    /**
     * 获取一个新 Key
     *
     * @throws Exception
     */
    private static void getNewKey() throws Exception {
        byte[] key = SM4Util.generateKey();
        String newKeyString = Base64.getEncoder().encodeToString(key);
        System.out.println("key:" + newKeyString);
    }

    public static void main(String[] args) throws Exception {
        getNewKey();
        String data = "123456";
        try {
            byte[] keyByte = Base64.getDecoder().decode(loadKey());
            byte[] cipherText = SM4Util.encrypt_ECB_Padding(keyByte, data.getBytes());
            String dataEncrypt = Base64.getEncoder().encodeToString(cipherText);
            System.out.println(dataEncrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}